LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;

entity serial_memory is
  port (clk : in std_logic;
		rstn : in std_logic;
		done : in std_logic;
		data : out std_logic_vector(15 downto 0);
		valid : out std_logic
		);
end entity;

architecture rtl of serial_memory is
	signal current_word : unsigned(2 downto 0);
begin
	process(clk, rstn, current_word, done)
	begin
		if rstn = '0' then
			current_word <= "000";
		else
			if rising_edge(clk) then
				if done = '1' then
					if current_word < 7 then
						current_word <= current_word + 1;
					end if;
				end if;
			end if;
		end if;
	end process;
	
	process(current_word, rstn)
	begin
		case current_word is
		when "000" => data <= "0000100000010000";
		when "001" => data <= "0000110000000001";
		when others => data <= "0000000000000000";
		end case;
		if rstn = '0' then
			valid <= '0';
		else
			if current_word < 2 then
				valid <= '1';
			else
				valid <= '0';
			end if;
		end if;
	end process;
end rtl;

LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;

entity serial_control is
  port (clk : in std_logic;
		rstn : in std_logic;
		data : in std_logic_vector(15 downto 0);
		start : in std_logic;
		scl : out std_logic;
		sda : out std_logic;
		scen : out std_logic;
		done : out std_logic
		);
end entity;

architecture rtl of serial_control is
    signal state : unsigned(8 downto 0);
	signal i_data : std_logic_vector(15 downto 0);
begin
	process(clk, rstn, state, start, data, i_data)
	begin
		if rstn = '0' then
			i_data <= (OTHERS => '0');
			state <= (OTHERS => '1');
		else
			if rising_edge(clk) then
				if state = 511 and start = '1' then
					state <= "000000000";
					i_data <= data;
				elsif state >= 320 then
					state <= "111111111";
				else 
					state <= state + 1;
					if state(3 downto 0) = 15 then
						i_data <= i_data(14 downto 0) & "0";
					end if;
				end if;
			end if;
		end if;
	end process;
	
	sda <= i_data(15);

	process(rstn, state)
	begin
		if rstn = '0' then
			scl <= '0';
		else
			if state(8) = '0' then
				scl <= state(3);
			else
				scl <= '0';
			end if;
		end if;
	end process;

	process(clk, rstn, state)
	begin
		if rstn = '0' then
			scen <= '0';
		else
			if rising_edge(clk) then
				if state < 264 then
					scen <= '0';
				else 
					scen <= '1';
				end if;
			end if;
		end if;
	end process;

	process(clk, rstn, state)
	begin
		if rstn = '0' then
			done <= '0';
		else
			if rising_edge(clk) then
				if state = 511 then
					done <= '1';
				else 
					done <= '0';
				end if;
			end if;
		end if;
	end process;
end rtl;

LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;

entity reset_generator is
  port (clk : in std_logic;
		rstn : in std_logic;
		ctrl_rstn : out std_logic;
		lcd_restn : out std_logic
		);
end entity;

architecture rtl of reset_generator is
    signal state : unsigned(20 downto 0);
begin
	process(clk, rstn)
	begin
		if rstn = '0' then
			state <= (OTHERS => '0');
		else
			if rising_edge(clk) then
				if state < 280000 then
					state <= state + 1;
				else
					state <= (OTHERS => '1');
				end if;
			end if;
		end if;
	end process;
	
	process(state)
	begin
		if state < 250000 then
			ctrl_rstn <= '0';
			lcd_restn <= '1';
		elsif state < 280000 then
			ctrl_rstn <= '0';
			lcd_restn <= '0';
		else
			ctrl_rstn <= '1';
			lcd_restn <= '1';
		end if;
	end process;
end architecture;
